﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;

namespace QueueManager.Service
{

  /// <summary>
  /// The queue settings section
  /// </summary>
  /// <remarks></remarks>
  public class QueueSection : ConfigurationSection
  {

    [ConfigurationProperty("", IsDefaultCollection = true)]
    [ConfigurationCollection(typeof(QueueSetting))]
    public QueueSettingsCollection Queues
    {      
      get { return (QueueSettingsCollection)base[""]; }
    }

  }

  /// <summary>
  /// The queue settings
  /// </summary>
  /// <remarks></remarks>
  public sealed class QueueSetting : ConfigurationElement
  {

    private const string NameProperty = "name";
    private const string QueueIdProperty = "queueid";
    private const string TempQueueIdProperty = "tempqueueid";
    private const string TempQueueAgeProperty = "tempqueueage";
    private const string SendVerificationMailProperty = "sendverificationmail";
    private const string IgnoreListProperty = "ignorelist";
    private const string MoveIgnoredProperty = "moveignored";
    private const string VerificationMailFromProperty = "verificationmail-from";
    private const string VerificationMailBccProperty = "verificationmail-bcc";
    private const string VerificationMailSubjectProperty = "verificationmail-subject";
    private const string VerificationMailTemplateProperty = "verificationmail-template";
    private const string VerificationMailUseHtmlProperty = "verificationmail-usehtml";
    private const string VerificationMailUrlProperty = "verificationmail-url";
    private const string CreateContactProperty = "createcontact";
    private const string AllowOnlyToProperty = "allowonlyto";
    private const string AllowOnlyToReplyProperty = "allowonlyto-reply";
    private const string AllowOnlyToNotifyProperty = "allowonlyto-notify";
    private const string AllowOnlyToFromProperty = "allowonlyto-from";
    private const string AllowOnlyToTemplateProperty = "allowonlyto-template";
    private const string AllowOnlyToSubjectProperty = "allowonlyto-subject";
    private const string AllowOnlyToUseHtmlProperty = "allowonlyto-usehtml";
    private const string MatchCaseTicketNumberProperty = "matchcaseticketnumber";
    private const string SendCaseMailProperty = "sendcasemail";
    private const string CaseMailFromProperty = "casemail-from";
    private const string CaseMailFromTypeProperty = "casemail-fromtype";
    private const string CaseMailNotifyProperty = "casemail-notify";
    private const string CaseMailSubjectProperty = "casemail-subject";
    private const string CaseMailTemplateProperty = "casemail-template";
    private const string CaseMailUseHtmlProperty = "casemail-usehtml";
    private const string UpdateCaseDescriptionProperty = "updatecasedescription";
    private const string IntervalProperty = "interval";
    private const string ResolveParentProperty = "resolveparent";
    private const string ResolveParentNotifyProperty = "resolveparent-notify";
    private const string ResolveParentFromProperty = "resolveparent-from";
    private const string SendCaseNotificationProperty = "sendcasenotificationmail";
    private const string CaseNotificationFromProperty = "casenotification-from";
    private const string CaseNotificationToProperty = "casenotification-to";
    private const string CaseNotificationSubjectProperty = "casenotification-subject";
    private const string CaseNotificationTemplateProperty = "casenotification-template";
    private const string CaseNotificationUseHtmlProperty = "casenotification-usehtml";
    private const string CaseAttributesProperty = "caseattributes";
    private const string RemoveRepliesFromQueueProperty = "removerepliesfromqueue";
    private const string MapCaseToAccountProperty = "mapcasetoaccount";
    private const string SetResponsibleContactProperty = "setresponsiblecontact";

    private const string ParentAccountMissingProperty = "parentaccountmissing";
    public QueueSetting()
    {
    }

    public QueueSetting(string elementName)
    {
      Name = elementName;
    }

    [ConfigurationProperty(NameProperty, IsKey = true, IsRequired = true)]
    public string Name
    {
      get { return (string)this[NameProperty]; }
      set { this[NameProperty] = value; }
    }

    [ConfigurationProperty(IntervalProperty, IsRequired = true)]
    public int Interval
    {
      get { return (int)this[IntervalProperty]; }
      set { this[IntervalProperty] = value; }
    }

    [ConfigurationProperty(SendVerificationMailProperty, DefaultValue = false)]
    public bool SendVerificationMail
    {
      get { return (bool)this[SendVerificationMailProperty]; }
      set { this[SendVerificationMailProperty] = value; }
    }

    [ConfigurationProperty(CreateContactProperty, DefaultValue = true)]
    public bool CreateContact
    {
      get { return (bool)this[CreateContactProperty]; }
      set { this[CreateContactProperty] = value; }
    }

    [ConfigurationProperty(ResolveParentProperty, DefaultValue = false, IsRequired = false)]
    public bool ResolveParent
    {
      get { return (bool)this[ResolveParentProperty]; }
      set { this[ResolveParentProperty] = value; }
    }

    [ConfigurationProperty(ResolveParentNotifyProperty, DefaultValue = "", IsRequired = false)]
    public string ResolveParentNotify
    {
      get { return (string)this[ResolveParentNotifyProperty]; }
      set { this[ResolveParentNotifyProperty] = value; }
    }

    [ConfigurationProperty(ResolveParentFromProperty, DefaultValue = "", IsRequired = false)]
    public string ResolveParentFrom
    {
      get { return (string)this[ResolveParentFromProperty]; }
      set { this[ResolveParentFromProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToProperty, DefaultValue = false, IsRequired = false)]
    public bool AllowOnlyTo
    {
      get { return (bool)this[AllowOnlyToProperty]; }
      set { this[AllowOnlyToProperty] = value; }
    }

    [ConfigurationProperty(IgnoreListProperty, IsRequired = false)]
    public string IgnoreList
    {
      get { return (string)this[IgnoreListProperty]; }
      set { this[IgnoreListProperty] = value; }
    }

    [ConfigurationProperty(MoveIgnoredProperty, DefaultValue = false, IsRequired = false)]
    public bool MoveIgnored
    {
      get { return (bool)this[MoveIgnoredProperty]; }
      set { this[MoveIgnoredProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToNotifyProperty, IsRequired = false)]
    public string AllowOnlyToNotify
    {
      get { return (string)this[AllowOnlyToNotifyProperty]; }
      set { this[AllowOnlyToNotifyProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToFromProperty, IsRequired = false)]
    public string AllowOnlyToFrom
    {
      get { return (string)this[AllowOnlyToFromProperty]; }
      set { this[AllowOnlyToFromProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToReplyProperty, IsRequired = false, DefaultValue = true)]
    public bool AllowOnlyToReply
    {
      get { return (bool)this[AllowOnlyToReplyProperty]; }
      set { this[AllowOnlyToReplyProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToUseHtmlProperty, IsRequired = false, DefaultValue = true)]
    public bool AllowOnlyToUseHtml
    {
      get { return (bool)this[AllowOnlyToUseHtmlProperty]; }
      set { this[AllowOnlyToUseHtmlProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToSubjectProperty, IsRequired = false)]
    public string AllowOnlyToSubject
    {
      get { return (string)this[AllowOnlyToSubjectProperty]; }
      set { this[AllowOnlyToSubjectProperty] = value; }
    }

    [ConfigurationProperty(AllowOnlyToTemplateProperty, IsRequired = false)]
    public string AllowOnlyToTemplate
    {
      get { return (string)this[AllowOnlyToTemplateProperty]; }
      set { this[AllowOnlyToTemplateProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailFromProperty, IsRequired = false)]
    public string VerificationMailFrom
    {
      get { return (string)this[VerificationMailFromProperty]; }
      set { this[VerificationMailFromProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailBccProperty, IsRequired = false)]
    public string VerificationMailBcc
    {
      get { return (string)this[VerificationMailBccProperty]; }
      set { this[VerificationMailBccProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailSubjectProperty, IsRequired = false)]
    public string VerificationMailSubject
    {
      get { return (string)this[VerificationMailSubjectProperty]; }
      set { this[VerificationMailSubjectProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailTemplateProperty, IsRequired = false)]
    public string VerificationMailTemplate
    {
      get { return (string)this[VerificationMailTemplateProperty]; }
      set { this[VerificationMailTemplateProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailUrlProperty, IsRequired = false)]
    public string VerificationMailUrl
    {
      get { return (string)this[VerificationMailUrlProperty]; }
      set { this[VerificationMailUrlProperty] = value; }
    }

    [ConfigurationProperty(VerificationMailUseHtmlProperty, IsRequired = false, DefaultValue = true)]
    public bool VerificationMailUseHtml
    {
      get { return (bool)this[VerificationMailUseHtmlProperty]; }
      set { this[VerificationMailUseHtmlProperty] = value; }
    }

    [ConfigurationProperty(SendCaseMailProperty, DefaultValue = true)]
    public bool SendCaseMail
    {
      get { return (bool)this[SendCaseMailProperty]; }
      set { this[SendCaseMailProperty] = value; }
    }

    [ConfigurationProperty(QueueIdProperty, IsRequired = true)]
    public string QueueId
    {
      get { return (string)this[QueueIdProperty]; }
      set { this[QueueIdProperty] = value; }
    }

    [ConfigurationProperty(TempQueueIdProperty, IsRequired = false)]
    public string TempQueueId
    {
      get { return (string)this[TempQueueIdProperty]; }
      set { this[TempQueueIdProperty] = value; }
    }

    [ConfigurationProperty(TempQueueAgeProperty, IsRequired = false, DefaultValue = 0)]
    public int TempQueueAge
    {
      get { return (int)this[TempQueueAgeProperty]; }
      set { this[TempQueueAgeProperty] = value; }
    }

    [ConfigurationProperty(MatchCaseTicketNumberProperty, IsRequired = false, DefaultValue = false)]
    public bool MatchCaseTicketNumber
    {
      get { return (bool)this[MatchCaseTicketNumberProperty]; }
      set { this[MatchCaseTicketNumberProperty] = value; }
    }

    [ConfigurationProperty(CaseMailFromProperty, IsRequired = false)]
    public string CaseMailFrom
    {
      get { return (string)this[CaseMailFromProperty]; }
      set { this[CaseMailFromProperty] = value; }
    }

    [ConfigurationProperty(CaseMailFromTypeProperty, IsRequired = false)]
    public string CaseMailFromType
    {
      get { return (string)this[CaseMailFromTypeProperty]; }
      set { this[CaseMailFromTypeProperty] = value; }
    }

    [ConfigurationProperty(CaseMailNotifyProperty, IsRequired = false)]
    public string CaseMailNotify
    {
      get { return (string)this[CaseMailNotifyProperty]; }
      set { this[CaseMailNotifyProperty] = value; }
    }

    [ConfigurationProperty(CaseMailSubjectProperty, IsRequired = false)]
    public string CaseMailSubject
    {
      get { return (string)this[CaseMailSubjectProperty]; }
      set { this[CaseMailSubjectProperty] = value; }
    }

    [ConfigurationProperty(CaseMailTemplateProperty, IsRequired = false)]
    public string CaseMailTemplate
    {
      get { return (string)this[CaseMailTemplateProperty]; }
      set { this[CaseMailTemplateProperty] = value; }
    }

    [ConfigurationProperty(CaseMailUseHtmlProperty, IsRequired = false, DefaultValue = true)]
    public bool CaseMailUseHtml
    {
      get { return (bool)this[CaseMailUseHtmlProperty]; }
      set { this[CaseMailUseHtmlProperty] = value; }
    }

    [ConfigurationProperty(UpdateCaseDescriptionProperty, DefaultValue = false)]
    public bool UpdateCaseDescription
    {
      get { return (bool)this[UpdateCaseDescriptionProperty]; }
      set { this[UpdateCaseDescriptionProperty] = value; }
    }

    [ConfigurationProperty(SendCaseNotificationProperty, DefaultValue = false)]
    public bool SendCaseNotification
    {
      get { return (bool)this[SendCaseNotificationProperty]; }
      set { this[SendCaseNotificationProperty] = value; }
    }

    [ConfigurationProperty(CaseNotificationFromProperty, IsRequired = false)]
    public string CaseNotificationFrom
    {
      get { return (string)this[CaseNotificationFromProperty]; }
      set { this[CaseNotificationFromProperty] = value; }
    }

    [ConfigurationProperty(CaseNotificationToProperty, IsRequired = false)]
    public string CaseNotificationTo
    {
      get { return (string)this[CaseNotificationToProperty]; }
      set { this[CaseNotificationToProperty] = value; }
    }

    [ConfigurationProperty(CaseNotificationSubjectProperty, IsRequired = false)]
    public string CaseNotificationSubject
    {
      get { return (string)this[CaseNotificationSubjectProperty]; }
      set { this[CaseNotificationSubjectProperty] = value; }
    }

    [ConfigurationProperty(CaseNotificationTemplateProperty, IsRequired = false)]
    public string CaseNotificationTemplate
    {
      get { return (string)this[CaseNotificationTemplateProperty]; }
      set { this[CaseNotificationTemplateProperty] = value; }
    }

    [ConfigurationProperty(CaseNotificationUseHtmlProperty, DefaultValue = false)]
    public bool CaseNotificationUseHtml
    {
      get { return (bool)this[CaseNotificationUseHtmlProperty]; }
      set { this[CaseNotificationUseHtmlProperty] = value; }
    }

    [ConfigurationProperty(CaseAttributesProperty, IsRequired = false)]
    public string CaseAttributes
    {
      get { return (string)this[CaseAttributesProperty]; }
      set { this[CaseAttributesProperty] = value; }
    }

    [ConfigurationProperty(RemoveRepliesFromQueueProperty, DefaultValue = false, IsRequired = false)]
    public bool RemoveRepliesFromQueue
    {
      get { return (bool)this[RemoveRepliesFromQueueProperty]; }
      set { this[RemoveRepliesFromQueueProperty] = value; }
    }

    [ConfigurationProperty(MapCaseToAccountProperty, DefaultValue = false, IsRequired = false)]
    public bool MapCaseToAccount
    {
      get { return (bool)this[MapCaseToAccountProperty]; }
      set { this[MapCaseToAccountProperty] = value; }
    }

    [ConfigurationProperty(SetResponsibleContactProperty, DefaultValue = false, IsRequired = false)]
    public bool SetResponsibleContact
    {
      get { return (bool)this[SetResponsibleContactProperty]; }
      set { this[SetResponsibleContactProperty] = value; }
    }

    [ConfigurationProperty(ParentAccountMissingProperty, DefaultValue = false, IsRequired = false)]
    public bool ParentAccountMissing
    {
      get { return (bool)this[ParentAccountMissingProperty]; }
      set { this[ParentAccountMissingProperty] = value; }
    }

  }

  public sealed class QueueSettingsCollection : ConfigurationElementCollection<QueueSetting>
  {

    public QueueSettingsCollection()
      : base(StringComparer.CurrentCultureIgnoreCase)
    {
    }

    protected override ConfigurationElement CreateNewElement()
    {
      return new QueueSetting();
    }

    protected override ConfigurationElement CreateNewElement(string elementName)
    {
      return new QueueSetting(elementName);
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
      return ((QueueSetting)element).Name;
    }

  }

  public abstract class ConfigurationElementCollection<T> : ConfigurationElementCollection where T : ConfigurationElement
  {


    protected ConfigurationElementCollection()
    {
    }

    protected ConfigurationElementCollection(IComparer comparer)
      : base(comparer)
    {
    }

    public T this[int index]
    {
      get { return (T)this[index]; }
      set { this[index] = value; }
    }

    public T this[string name]
    {
      get { return (T)this[name]; }
      set { this[name] = value; }
    }

    public void Add(T settings)
    {
      BaseAdd(settings);
    }

    public void Clear()
    {
      BaseClear();
    }

    public void Remove(string name)
    {
      BaseRemove(name);
    }

    public void Remove(T settings)
    {
      BaseRemove(GetElementKey(settings));
    }

    public void RemoveAt(int index)
    {
      BaseRemoveAt(index);
    }

    public int IndexOf(T settings)
    {
      return BaseIndexOf(settings);
    }

    protected override void BaseAdd(int index, ConfigurationElement element)
    {
      base.BaseAdd(index, element);
    }

  }

}
